home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 24
/
AACD 24.iso
/
AACD
/
Resources
/
Online
/
OpenURL
/
Developer
/
Source
/
handler.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-26
|
5KB
|
223 lines
/*
** OpenURL-Handler - Asynch ARexx handler for openurl.library
** Written by Troels Walsted Hansen <troels@thule.no>
** Placed in the public domain.
**
** This is the one and only source file for the handler.
*/
#include <proto/exec.h>
#include <clib/dos_protos.h>
#include <clib/rexxsyslib_protos.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/rexxsyslib_pragmas.h>
#include <exec/memory.h>
#include <rexx/rxslib.h>
#include <rexx/errors.h>
#include <string.h>
#include "handler.h"
#define SAVEDS __saveds
extern void kprintf(const char *, ...);
/**************************************************************************
*
* Prototypes for library and Local, non-library functions.
*
*/
VOID SAVEDS HandlerProcessEntry(VOID);
static BOOL SendRexxMsg(struct MsgPort *replyport, STRPTR rxport, STRPTR rxcmd);
/**************************************************************************
*
* Definitions and global variables.
*
*/
struct ExecBase *SysBase;
struct DosLibrary *DOSBase = NULL;
struct RxsLib *RexxSysBase = NULL;
static const char *version = "$VER: OpenURL-Handler 1.0 " __AMIGADATE__;
/**************************************************************************
*
* This function will be called when the handler is started.
*
*/
VOID SAVEDS HandlerProcessEntry(VOID)
{
struct Process *me;
struct HandlerMsg *starthm = NULL;
struct SignalSemaphore *ss;
ULONG sigs, sigmask, msgcount = 0;
struct MsgPort *mp = NULL;
struct Message *msg;
SysBase = *(struct ExecBase **)4;
me = (struct Process *)FindTask(NULL);
/* get startupmsg */
while(!starthm)
{
/* should the handler accidentally be launched from somewhere other
than the library, it can be broken with CTRL-C */
sigs = Wait((1 << me->pr_MsgPort.mp_SigBit) | SIGBREAKF_CTRL_C);
if(sigs & SIGBREAKF_CTRL_C) return;
starthm = (struct HandlerMsg *)GetMsg(&me->pr_MsgPort);
}
ss = starthm->hm_Semaphore;
ObtainSemaphore(ss);
/* initialise everything */
if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36)))
goto done;
if(!(RexxSysBase = (struct RxsLib *)OpenLibrary("rexxsyslib.library", 33)))
goto done;
if(!(mp = CreateMsgPort()))
goto done;
/* reply startup msg to signal readyness */
starthm->hm_Success = TRUE;
starthm->hm_MsgPort = mp;
ReplyMsg((struct Message *)starthm);
starthm = NULL;
/* enter input loop */
sigmask = (1 << mp->mp_SigBit) | SIGBREAKF_CTRL_C;
for(;;)
{
sigs = Wait(sigmask);
if(sigs & SIGBREAKF_CTRL_C) break;
else
{
while((msg = GetMsg(mp)))
{
if(msg->mn_Node.ln_Type == NT_REPLYMSG)
{
DeleteArgstring(((struct RexxMsg *)msg)->rm_Args[0]);
DeleteRexxMsg((struct RexxMsg *)msg);
msgcount--;
}
else
{
struct HandlerMsg *hm = (struct HandlerMsg *)msg;
if(hm->hm_Type == HMT_AREXX)
{
hm->hm_Success = SendRexxMsg(mp, hm->hm_ARexxPort, hm->hm_ARexxCmd);
if(hm->hm_Success) msgcount++;
}
ReplyMsg(msg);
}
}
}
}
done:
/* release semaphore to indicate we're no longer running.
this will stop the library from sending any more msgs */
ReleaseSemaphore(ss);
/* wait for return of all msgs */
while(msgcount)
{
WaitPort(mp);
while((msg = GetMsg(mp)))
{
if(msg->mn_Node.ln_Type == NT_REPLYMSG)
{
DeleteArgstring(((struct RexxMsg *)msg)->rm_Args[0]);
DeleteRexxMsg((struct RexxMsg *)msg);
msgcount--;
}
else
{
((struct HandlerMsg *)msg)->hm_Success = FALSE;
ReplyMsg(msg);
}
}
}
/* empty out msgport */
while((msg = GetMsg(mp)))
{
((struct HandlerMsg *)msg)->hm_Success = FALSE;
ReplyMsg(msg);
}
/* free resources */
if(mp) DeleteMsgPort(mp);
CloseLibrary((struct Library *)RexxSysBase);
CloseLibrary((struct Library *)DOSBase);
/* the startup msg needs to be replied now if a resource
allocation failed */
if(starthm)
{
starthm->hm_Success = FALSE;
ReplyMsg((struct Message *)starthm);
}
}
/**************************************************************************/
static BOOL SendRexxMsg(struct MsgPort *replyport, STRPTR rxport, STRPTR rxcmd)
{
struct RexxMsg *rxmsg;
if((rxmsg = CreateRexxMsg(replyport, NULL, NULL)))
{
rxmsg->rm_Action = RXCOMM | RXFF_STRING | RXFF_NOIO;
/* create the arg string */
if((rxmsg->rm_Args[0] = CreateArgstring(rxcmd, strlen(rxcmd))))
{
struct MsgPort *targetport;
/* find the named rexx port and put the rexx msg to it */
Forbid();
if((targetport = FindPort(rxport)))
{
PutMsg(targetport, (struct Message *)rxmsg);
Permit();
return(TRUE);
}
Permit();
DeleteArgstring(rxmsg->rm_Args[0]);
}
DeleteRexxMsg(rxmsg);
}
return(FALSE);
}